#include "widget.h"
#include <QPushButton>
#include <QDebug>
#include "mypushbutton.h"


Widget::Widget(QWidget *parent)
        : QWidget(parent)
{
    // 创建第一个按钮
    auto *btn = new QPushButton;
//    btn->show();    // show以顶层方式弹出窗口控件
    // 让btn对象 依赖Widget窗口中
    btn->setParent(this);
    // 显示文本
    btn->setText("第一个按钮");

    // 创建第二个按钮 按照控件的大小创建窗口
    auto *btn2 = new QPushButton("第二个按钮", this);

    // 设置按钮的大小
    btn2->resize(150, 50);

    /**
     * QT窗口坐标系
     * 以左上角为原点（0，0），X向右增加，Y向下增加。
     * 对于嵌套窗口，其坐标是相对父窗口来说的。
     */
    // 移动btn按钮
    btn->move(100, 100);

    // 重置窗口的大小
    resize(600, 400);

    // 设置固定窗口大小
    setFixedSize(600, 400);

    // 设置窗口标题
    setWindowTitle("第一个窗口");

    /**
     * btn btn2是使用new申请的，但是不需要我们手动delete
     * 原因是 btn btn2都设置了Parent，Parent会将它们加入到对象树中，
     * QObject对象会释放所有children对象
     * 为了验证自动delete的过程，我们创建一个myPushButton类继承QPushButton
     *
     * 对象树：当创建的对象在堆区时候，如果指定的父亲是QObject的派生类，
     *        该对象会被放入对象树中，不用管理释放的操作。
     */

    // 创建一个自己的按钮对象
    auto *myBtn = new MyPushButton;
    myBtn->setText("我自己的按钮");
    myBtn->move(200, 0);
    myBtn->setParent(this); // 设置到对象树中
    // 注意查看，关闭窗口时，析构函数中的信息将被打印出来

    /**
     * 信号和槽
     *
     *  点击按钮，关闭窗口：
     *     按钮       -->     点击      -->    窗口    -->    关闭窗口
     *   信号的发送者  -->  发送的具体信号 --> 信号的接收者 --> 信号的处理（槽）
     *
     * 伪代码：
     *    connect(信号的发送者，发送的具体信号，信号的接收者，信号的处理（槽）)
     *
     * 信号和槽 是相互独立的：
     *   按下按钮，就一定窗口关闭吗？
     *   要窗口关闭，就一定要按下按钮吗？
     * 信号槽的优点：松散耦合，信号发送端 和 接收端 本身是没有关联的，通过connect连接 将两端 耦合在一起
     *
     * connect函数：
     *  参数1 信号发送者的指针
     *  参数2 信号函数的地址（函数名本身就是地址，函数的地址，就是二级指针）
     *  参数3 接收者的地址
     *  参数4 槽的地址
     */
//     connect(myBtn, &MyPushButton::clicked, this, &Widget::close);
     // 也可以使用父类的名字 QPushButton::clicked  QWidget::close
     connect(myBtn, &QPushButton::clicked, this, &QWidget::close);
}

/**
 * 是先析构Widget对象，还是先析构Widget下面的儿子对象
 * 从打印信息上来看，Widget的析构函数信息先被打印
 * 原因是：析构Widget时，调用Widget的析构函数，Widget的析构函数中的信息被打印，但是还没有真正释放Widget对象
 *        Widget开始找自己儿子的对象，调用儿子对象的析构（每个儿子对象再找自己是否有儿子对象），等所有儿子的对象释放完成后，再释放自己。
 */
Widget::~Widget()
{
    qDebug() << "我的窗口Widget的析构调用";
    // 儿子对象在此处释放。
    // 所以打印的信息是先打印的父亲的析构信息，再打印的儿子的析构信息
}

